```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>最长递增子序列 | 算法可视化</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #d946ef 100%);
        }
        .code-block {
            background-color: #1e293b;
            border-radius: 0.75rem;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
        }
        .card-hover:hover {
            transform: translateY(-4px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .highlight {
            position: relative;
            z-index: 1;
        }
        .highlight:after {
            content: '';
            position: absolute;
            bottom: 2px;
            left: 0;
            width: 100%;
            height: 8px;
            background-color: #a5b4fc;
            z-index: -1;
            opacity: 0.5;
            transition: all 0.2s ease;
        }
        .highlight:hover:after {
            height: 14px;
            opacity: 0.8;
        }
        .mermaid {
            background-color: white;
            border-radius: 0.75rem;
            padding: 1.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
        }
    </style>
</head>
<body class="min-h-screen">
    <!-- Hero Section -->
    <section class="hero-gradient text-white">
        <div class="container mx-auto px-6 py-24">
            <div class="max-w-4xl mx-auto text-center">
                <h1 class="text-5xl font-bold mb-6 leading-tight">最长递增子序列</h1>
                <p class="text-xl opacity-90 mb-8">探索动态规划与二分查找在算法问题中的精妙应用</p>
                <div class="flex justify-center space-x-4">
                    <a href="#problem" class="px-6 py-3 bg-white text-indigo-600 rounded-full font-medium hover:bg-opacity-90 transition duration-300 transform hover:scale-105 shadow-lg">
                        <i class="fas fa-book-open mr-2"></i>问题详解
                    </a>
                    <a href="#solution" class="px-6 py-3 bg-opacity-20 border border-white rounded-full font-medium hover:bg-opacity-30 transition duration-300 transform hover:scale-105">
                        <i class="fas fa-lightbulb mr-2"></i>解决方案
                    </a>
                </div>
            </div>
        </div>
    </section>

    <!-- Problem Section -->
    <section id="problem" class="py-20 bg-white">
        <div class="container mx-auto px-6 max-w-5xl">
            <div class="mb-12 text-center">
                <h2 class="text-3xl font-bold mb-4 text-gray-800">题目描述</h2>
                <div class="w-20 h-1 bg-indigo-500 mx-auto"></div>
            </div>
            
            <div class="bg-gray-50 rounded-xl p-8 shadow-sm mb-16">
                <p class="text-lg leading-relaxed text-gray-700 mb-6">
                    给定一个整数数组 <span class="font-bold text-indigo-600">nums</span>，找到其中最长严格递增子序列的长度。<br>
                    子序列是由数组派生而来的序列，删除（或不删除）数组中的元素而不改变其余元素的顺序。
                </p>
                
                <div class="flex flex-col md:flex-row gap-8">
                    <div class="flex-1 bg-blue-50 p-6 rounded-lg">
                        <h3 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
                            <i class="fas fa-list-ol text-indigo-500 mr-3"></i>示例
                        </h3>
                        <div class="space-y-3">
                            <div>
                                <p class="text-gray-600">输入:</p>
                                <p class="font-mono bg-gray-100 p-2 rounded">[10,9,2,5,3,7,101,18]</p>
                            </div>
                            <div>
                                <p class="text-gray-600">输出:</p>
                                <p class="font-mono bg-gray-100 p-2 rounded">4</p>
                            </div>
                            <div>
                                <p class="text-gray-600">解释:</p>
                                <p class="text-gray-700">
                                    最长递增子序列是 [2,3,7,101]，因此长度为 4。
                                </p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex-1 bg-amber-50 p-6 rounded-lg">
                        <h3 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
                            <i class="fas fa-exclamation-circle text-amber-500 mr-3"></i>注意事项
                        </h3>
                        <ul class="space-y-2 text-gray-700">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-amber-500 mt-1 mr-2"></i>
                                <span>子序列不同于子数组，不需要元素连续</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-amber-500 mt-1 mr-2"></i>
                                <span>要求严格递增，即 nums[i] > nums[j] 当 i > j</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-amber-500 mt-1 mr-2"></i>
                                <span>可能有多个最长递增子序列，只需返回长度</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
            
            <!-- Visualization -->
            <div class="mb-16">
                <h3 class="text-2xl font-bold mb-6 text-gray-800 flex items-center">
                    <i class="fas fa-project-diagram text-purple-500 mr-3"></i>算法可视化
                </h3>
                <div class="mermaid">
                    graph TD
                        A[最长递增子序列问题] --> B[动态规划法]
                        A --> C[贪心+二分法]
                        B --> D[定义dp[i]为以nums[i]结尾的最长子序列长度]
                        B --> E[时间复杂度O(n²)]
                        B --> F[空间复杂度O(n)]
                        C --> G[维护tails数组记录最小结尾元素]
                        C --> H[时间复杂度O(n log n)]
                        C --> I[空间复杂度O(n)]
                </div>
            </div>
        </div>
    </section>

    <!-- Solution Section -->
    <section id="solution" class="py-20 bg-gray-50">
        <div class="container mx-auto px-6 max-w-5xl">
            <div class="mb-12 text-center">
                <h2 class="text-3xl font-bold mb-4 text-gray-800">解决方案</h2>
                <div class="w-20 h-1 bg-indigo-500 mx-auto"></div>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-16">
                <!-- DP Solution -->
                <div class="bg-white p-8 rounded-xl shadow-sm card-hover transition duration-300">
                    <div class="flex items-center mb-6">
                        <div class="bg-indigo-100 w-12 h-12 rounded-full flex items-center justify-center mr-4">
                            <i class="fas fa-sitemap text-indigo-600 text-xl"></i>
                        </div>
                        <h3 class="text-2xl font-bold text-gray-800">动态规划法</h3>
                    </div>
                    
                    <div class="space-y-4 text-gray-700">
                        <p>
                            <span class="highlight font-medium">定义状态</span>: dp[i] 表示以 nums[i] 结尾的最长递增子序列长度
                        </p>
                        <p>
                            <span class="highlight font-medium">状态转移</span>: dp[i] = max(dp[j] + 1) 对所有 j < i 且 nums[j] < nums[i]
                        </p>
                        <p>
                            <span class="highlight font-medium">初始化</span>: 每个 dp[i] 初始为 1
                        </p>
                        <p>
                            <span class="highlight font-medium">结果</span>: max(dp[0...n-1])
                        </p>
                    </div>
                    
                    <div class="mt-6">
                        <div class="flex items-center text-sm text-gray-500 mb-2">
                            <i class="fas fa-clock mr-2"></i>
                            <span>时间复杂度: O(n²)</span>
                        </div>
                        <div class="flex items-center text-sm text-gray-500">
                            <i class="fas fa-memory mr-2"></i>
                            <span>空间复杂度: O(n)</span>
                        </div>
                    </div>
                </div>
                
                <!-- Binary Search Solution -->
                <div class="bg-white p-8 rounded-xl shadow-sm card-hover transition duration-300">
                    <div class="flex items-center mb-6">
                        <div class="bg-purple-100 w-12 h-12 rounded-full flex items-center justify-center mr-4">
                            <i class="fas fa-search text-purple-600 text-xl"></i>
                        </div>
                        <h3 class="text-2xl font-bold text-gray-800">贪心+二分查找</h3>
                    </div>
                    
                    <div class="space-y-4 text-gray-700">
                        <p>
                            <span class="highlight font-medium">维护数组</span>: tails[i] 表示长度为 i+1 的子序列的最小结尾元素
                        </p>
                        <p>
                            <span class="highlight font-medium">策略</span>: 对每个元素在 tails 中寻找插入位置进行更新
                        </p>
                        <p>
                            <span class="highlight font-medium">二分查找</span>: 优化搜索过程至 O(log n)
                        </p>
                        <p>
                            <span class="highlight font-medium">结果</span>: tails 数组的长度即为答案
                        </p>
                    </div>
                    
                    <div class="mt-6">
                        <div class="flex items-center text-sm text-gray-500 mb-2">
                            <i class="fas fa-clock mr-2"></i>
                            <span>时间复杂度: O(n log n)</span>
                        </div>
                        <div class="flex items-center text-sm text-gray-500">
                            <i class="fas fa-memory mr-2"></i>
                            <span>空间复杂度: O(n)</span>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- Code Section -->
            <div>
                <h3 class="text-2xl font-bold mb-6 text-gray-800 flex items-center">
                    <i class="fas fa-code text-blue-500 mr-3"></i>代码实现 (动态规划法)
                </h3>
                
                <div class="code-block p-6 mb-8">
                    <div class="flex items-center text-gray-400 mb-4">
                        <div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div>
                        <div class="w-3 h-3 bg-yellow-500 rounded-full mr-2"></div>
                        <div class="w-3 h-3 bg-green-500 rounded-full mr-4"></div>
                        <span class="text-sm">Java</span>
                    </div>
                    <pre class="text-gray-200 overflow-x-auto"><code>
public int lengthOfLIS(int[] nums) {
    // 处理边界情况
    if (nums == null || nums.length == 0) {
        return 0;
    }
    
    // 创建动态规划数组，dp[i]表示以nums[i]结尾的最长递增子序列长度
    int[] dp = new int[nums.length];
    // 初始化dp数组，每个元素自身就是长度为1的子序列
    Arrays.fill(dp, 1);
    
    // 最长递增子序列的长度
    int maxLength = 1;
    
    // 对于每个元素，计算以其结尾的最长递增子序列长度
    for (int i = 0; i < nums.length; i++) {
        // 检查所有在当前元素之前的元素
        for (int j = 0; j < i; j++) {
            // 如果当前元素大于之前的元素，可以形成递增序列
            if (nums[i] > nums[j]) {
                // 更新dp[i]为最大可能值
                dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }
        // 更新全局最长长度
        maxLength = Math.max(maxLength, dp[i]);
    }
    
    // 返回最长递增子序列的长度
    return maxLength;
}
                    </code></pre>
                </div>
                
                <div class="bg-blue-50 p-6 rounded-lg">
                    <h4 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-comment-dots text-blue-500 mr-3"></i>代码解析
                    </h4>
                    <div class="grid md:grid-cols-2 gap-4 text-gray-700">
                        <div class="bg-white p-4 rounded shadow-sm">
                            <div class="font-medium text-blue-600 mb-2">1. 初始化</div>
                            <p>创建dp数组并全部初始化为1，因为每个元素自身就是一个长度为1的子序列。</p>
                        </div>
                        <div class="bg-white p-4 rounded shadow-sm">
                            <div class="font-medium text-blue-600 mb-2">2. 双层循环</div>
                            <p>外层循环遍历每个元素，内层循环检查该元素之前的所有元素，寻找可以形成递增序列的组合。</p>
                        </div>
                        <div class="bg-white p-4 rounded shadow-sm">
                            <div class="font-medium text-blue-600 mb-2">3. 状态转移</div>
                            <p>当发现nums[i] > nums[j]时，更新dp[i]为max(dp[i], dp[j]+1)，表示可以扩展子序列。</p>
                        </div>
                        <div class="bg-white p-4 rounded shadow-sm">
                            <div class="font-medium text-blue-600 mb-2">4. 结果获取</div>
                            <p>最终结果不是dp[n-1]，而是dp数组中的最大值，因为最长子序列可能以任意元素结尾。</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>
```